package vip.zhenzicheng.nettybasic.sharehandler;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LineBasedFrameDecoder;
import lombok.AllArgsConstructor;
import vip.zhenzicheng.nettybasic.NettyConst;

import java.net.InetSocketAddress;
import java.util.logging.Logger;

/**
 * 基于Netty的服务器
 *
 * @author zhenzicheng
 * @date 2022-06-08 19:13
 */
@AllArgsConstructor
public class EchoServerMC {

  private static final Logger LOG = Logger.getLogger(EchoServerMC.class.getSimpleName());

  private final int port;

  public static void main(String[] args) throws InterruptedException {
    EchoServerMC echoServer = new EchoServerMC(NettyConst.ECHO_PORT);
    echoServer.start();
    LOG.info("服务器关闭");
  }

  public void start() throws InterruptedException {
    // 消息统计处理器，标注为可重用
    final MessageCountHandler messageCountHandler = new MessageCountHandler();

    // 线程组 reactor主从模式 boss负责监听连接 work负责处理连接
    EventLoopGroup boss = new NioEventLoopGroup();
    EventLoopGroup work = new NioEventLoopGroup();

    try {
      ServerBootstrap bootstrap = new ServerBootstrap();
      bootstrap.group(boss, work)
          .channel(NioServerSocketChannel.class)
          .localAddress(new InetSocketAddress(port))
          .childHandler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel channel) throws Exception {
              channel.pipeline().addLast(new LineBasedFrameDecoder(1024));
              channel.pipeline().addLast(messageCountHandler);
              channel.pipeline().addLast(new EchoServerMCHandler());
            }
          });
      ChannelFuture future = bootstrap.bind().sync();
      future.channel().closeFuture().sync();
    } finally {
      boss.shutdownGracefully().sync();
      work.shutdownGracefully().sync();
    }
  }

}
